package com.crawler.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.GZIPInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpUtil {

	private static Log log = LogFactory.getLog(HttpUtil.class);
	private static String defaultEncoding = "utf-8";// 默认请求编码

	/**
	 * 获取httpResponse
	 * 
	 * @param url
	 * @param headers
	 * @param params
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static CloseableHttpResponse getHttpResponse(String url, Map<String, String> headers,
			Map<String, String> params) {
		CloseableHttpClient httpclient = createHttpClient();
		HttpGet httpget = new HttpGet(url);
		if (headers != null && headers.keySet().size() > 0) {
			for (String key : headers.keySet()) {
				httpget.setHeader(key, headers.get(key));
			}
		}
		if (params != null && params.keySet().size() > 0) {
			for (String pkey : params.keySet()) {
				httpget.getParams().setParameter(pkey, params.get(pkey));
			}
		}
		CloseableHttpResponse response = null;
		try {
			response = httpclient.execute(httpget);
			return response;
		} catch (Exception e) {
			log.error(e);
		} finally {
		}
		return response;
	}

	public static CloseableHttpResponse postHttpResponse(String url, Map<String, String> headers,
			Map<String, String> params) {
		CloseableHttpClient httpclient = createHttpClient();
		HttpPost httppost = new HttpPost(url);
		if (headers != null && headers.keySet().size() > 0) {
			for (String key : headers.keySet()) {
				httppost.setHeader(key, headers.get(key));
			}
		}
		List<NameValuePair> paramslist = new ArrayList<NameValuePair>();
		if (params != null && params.keySet().size() > 0) {
			for (String pkey : params.keySet()) {
				String valueCache = null; //有些情况参数value为空，可能会出现空指针异常,故如果为null，则赋空值
				if (null == params.get(pkey)) {
					valueCache = "";
				} else {
					valueCache = params.get(pkey);
				}
				paramslist.add(new BasicNameValuePair(pkey, valueCache));
			}
		}
		try {
			httppost.setEntity(new UrlEncodedFormEntity(paramslist));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		CloseableHttpResponse response = null;
		try {
			response = httpclient.execute(httppost);
			return response;
		} catch (Exception e) {
			log.error(e);
		} finally {
		}
		return response;
	}
	
	/**
	 * 根据HttpResponse获取html
	 * 
	 * @param response
	 * @return
	 */
	public static String getHtmlByHttpResponse(CloseableHttpResponse response, String encoding) {
		if (response == null)
			return null;
		StringBuffer html = null;
		if (encoding == null || encoding.isEmpty())
			encoding = defaultEncoding;

		try {
			if (response.getEntity().getClass().getSimpleName().equals("GzipDecompressingEntity")) {

				InputStream in = null;
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				try {
					in = response.getEntity().getContent();
					GZIPInputStream gzip = new GZIPInputStream(in);
					byte[] buf = new byte[1024];
					int n;
					while ((n = gzip.read(buf)) != -1) {
						baos.write(buf, 0, n);
					}
					gzip.close();

				} catch (Exception e) {
					if (e.getMessage().contains("Not in GZIP format")) {
						byte[] buf = new byte[1024];
						int n;
						while ((n = in.read(buf)) != -1) {
							baos.write(buf, 0, n);
						}
					}
				} finally {
					in.close();
				}
				String str = new String(baos.toByteArray(), encoding);
				html = new StringBuffer(str);
			} else {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					html = new StringBuffer();
					long len = entity.getContentLength();
					if (len != -1) {
						try {
							html.append(EntityUtils.toString(entity));
						} catch (ParseException e) {
							log.error(e);
						} catch (IOException e) {
							log.error(e);
						} finally {
							response.close();
						}
					}
				}
			}
		} catch (Exception e) {
			log.error(e);
			e.printStackTrace();
		} finally {
		}
		if (html == null) {
			return null;
		}
		return html.toString();
	}

	/**
	 * 根据HttpResponse获取html
	 * 
	 * @param url
	 * @param headers
	 * @param params
	 * @return
	 */
	public static String getHtmlByHttpResponse(String url, String encoding, Map<String, String> headers,
			Map<String, String> params) {
		CloseableHttpResponse HttpResponse = getHttpResponse(url, headers, params);
		if (HttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			return getHtmlByHttpResponse(HttpResponse, encoding);
		}
		return null;
	}

	/**
	 * 根据HttpResponse获取html
	 * 
	 * @param url
	 * @return
	 */
	public static String getHtmlByHttpResponse(String url, String encoding) {
		CloseableHttpResponse HttpResponse = getHttpResponse(url, null, null);
		if (HttpResponse.getStatusLine().getStatusCode() == 200) {
			return getHtmlByHttpResponse(HttpResponse, encoding);
		}
		return null;
	}

	/**
	 * 创建默认httpclient
	 * 
	 * @return
	 */
	public final static CloseableHttpClient createHttpClient() {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		return httpclient;
	}
	/**
	 * 创建默认httpclient
	 * 
	 * @return
	 */
	public static HttpClient createHttpClient(int a) {
		HttpClient httpclient = HttpClients.createDefault();
		return httpclient;
	}


	/**
	 * 获取图片byte[]
	 * 
	 * @param url
	 *            图片url
	 * @param timeout
	 *            请求超时时间
	 * @param headers
	 *            请求头
	 * @return
	 */
	public static byte[] GetImage(String url, int timeout, Map<String, String> headers) {
		byte[] data = null;
		try {

			URL u = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			if (headers != null && headers.size() > 0) {
				Set<String> keys = headers.keySet();
				Iterator<String> it = keys.iterator();
				while (it.hasNext()) {
					String k = it.next().toString();
					if (k != null) {
						conn.setRequestProperty(k, headers.get(k));
					}
				}
			}
			conn.setConnectTimeout(timeout);
			InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据
			data = readInputStream(inStream);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
		}
		return data;
	}

	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[2048];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		inStream.close();
		return outStream.toByteArray();
	}
	/**
	 * 转换CloseableHttpResponse 成 String
	 * 
	 * @param httpResponse
	 * @return
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	public static String getHtml(CloseableHttpResponse httpResponse) throws IllegalStateException, IOException {
		String line = null;
		String html = "";
		if (httpResponse.getStatusLine().getStatusCode() == 200) {
			HttpEntity entity = httpResponse.getEntity();
			InputStream in = entity.getContent();
			BufferedReader reader = new BufferedReader(new InputStreamReader(in));
			while ((line = reader.readLine()) != null) {
				html = html + line;
			}
		}else {
			return null;
		}
		return html;
	}
	
	public static String getCookies(String target_url){
		String set_cookie = new String();
		try {
			URL obj = new URL(target_url); // 请求主页，去拿到服务器发过来的Set-Cookie
			URLConnection conn = obj.openConnection();
			Map<String, List<String>> map = conn.getHeaderFields(); // 显示响应Header信息
			for (Map.Entry<String, List<String>> entry : map.entrySet()) {
				String key = entry.getKey();
				List<String> value = entry.getValue();
				if ("Set-Cookie".equals(key)) {
					for (int i = 0; i < value.size(); i++) {
						set_cookie = set_cookie + ";" + value.get(i);
					}
					if (set_cookie.startsWith(";")) {
						set_cookie = set_cookie.substring(1, set_cookie.length());
					}
				}
			}
			System.out.println("获取服务器发送的Set-Cookie:" + set_cookie);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return set_cookie;
	}
}
